/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tpv;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author alex952
 */
public class EntradaXML extends Entrada
{
	//Atributos para la lectura de líneas

	private NodeList childs;
	private Integer nextChild;
	private String ruta;

	/**
	 * Constructor de la clase que recibe la ruta del xml
	 * @param ruta Ruta al fichero xml
	 */
	public EntradaXML(String ruta)
	{
		this.ruta = ruta;
	}

	/**
	 * Lee de la entrada xml la venta
	 * @return 
	 */
	@Override
	public Venta obtenerVenta()
	{
		String fi = "";
		Venta venta = null;
		Document dom = null;

		try
		{
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			dom = db.parse(ruta);
			dom.getDocumentElement().normalize();

			Element docEle = dom.getDocumentElement();

			venta = obtenerVentaDeXML(docEle);

			return venta;
		}
		catch (IOException e)
		{
			System.err.println("Ha habido un error en la lectura del fichero");

			return null;
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
			return null;
		}
	}

	/**
	 * Método dummy que no realiza nada ya que leemos todo el xml desde 
	 * obtenerVenta
	 * @param catalogo
	 * @return 
	 */
	@Override
	public Integer obtenerLinVenta(Catalogo catalogo)
	{
		if (childs.getLength() == nextChild)
		{
			return EntradaXML.FIN;
		}
		else
		{
			Node n = childs.item(nextChild++);
			if (n.getNodeType() == Node.ELEMENT_NODE)
			{
				Element lin = (Element) n;

				if (lin.getNodeName().equals("linventa"))
				{
					linea = obtenerLinVentaDeXML(lin, catalogo);

					return EntradaXML.LINEA;
				}
				else if (lin.getNodeName().equals("deshacerlinventa"))
				{
					return EntradaXML.DESLINEA;
				}
				else if (lin.getNodeName().equals("cancelarventa"))
				{
					return EntradaXML.DESVENTA;
				}
				else
				{
					return EntradaXML.OTHER;
				}
			}
			else
			{
				return EntradaXML.OTHER;
			}
		}
	}

	/**
	 * Función que pasa el xml de la venta a una variable local para su mejor
	 * manipulación
	 * @param ruta Ruta al fichero xml
	 * @return Retorna un string con el fichero xml
	 * @throws IOException 
	 */
	private String ficheroAString(String ruta) throws IOException
	{

		byte[] buffer = new byte[(int) new File(ruta).length()];
		BufferedInputStream f = null;

		try
		{
			f = new BufferedInputStream(new FileInputStream(ruta));
			f.read(buffer);
		}
		finally
		{
			if (f != null)
			{
				f.close();
			}
		}

		String cadena = new String(buffer);
		String ret = "";

		for (int i = 0; i < cadena.length(); i++)
		{
			Boolean etiq = false;
			char letra = cadena.charAt(i);

			if (letra == '<')
			{
				etiq = true;
				ret += letra;
			}
			else if (letra == '>')
			{
				etiq = false;
				ret += letra;
			}
			else
			{
				if (etiq || (!etiq && letra != ' ' && letra != '\n'))
				{
					ret += letra;
				}
			}
		}

		return ret;
	}

	/**
	 * Construye la venta a partir del nodo raíz del xml
	 * @param venta Nodo raíz DOM del xml
	 * @return Retorna la venta construida
	 */
	private Venta obtenerVentaDeXML(Element venta)
	{
		//Obtener datos del cliente
		NodeList nCliente = venta.getElementsByTagName("cliente");
		Element cliente = (Element) nCliente.item(0);

		Boolean fid = Boolean.parseBoolean(cliente.getAttribute("tarjetaFid"));
		Boolean emp = Boolean.parseBoolean(cliente.getAttribute("empleado"));

		//Obtener datos de la fecha
		NodeList nFecha = venta.getElementsByTagName("fecha");
		Element fecha = (Element) nFecha.item(0);

		String dia = fecha.getAttribute("dia");
		String hora = fecha.getAttribute("hora");
		String[] hm = hora.split(":");

		Venta v = new Venta(emp, fid, new Fecha(dia, Integer.parseInt(hm[0]), Integer.parseInt(hm[1])));
		childs = venta.getChildNodes();
		nextChild = 0;

		return v;
	}

	/**
	 * Obtiene un objeto LinVenta a partir de un nodo interno del xml
	 * @param linea Nodo interno del fichero xml
	 * @param catalogo Catálogo para la búsqueda del item de la línea
	 * @return Retorna una línea de venta construida para añadirla a una venta
	 */
	private LinVenta obtenerLinVentaDeXML(Element linea, Catalogo catalogo)
	{
		String cod = linea.getAttribute("codProd");
		Integer cant = Integer.parseInt(linea.getAttribute("cant"));

		LinVenta lv = new LinVenta(catalogo.obtenerItem(cod), cant);

		return lv;
	}
}
